#ifndef GAME_DEBUG_INTERFACE_H
#define GAME_DEBUG_INTERFACE_H
#include "game_platform.h"
#define DEBUG_DEGIN_HOT_ELEMENT(...) ;

struct debug_data_block {
    debug_data_block(const char *Name) { RecordDebugEvent(DebugType_OpenDataBlock, Name); }
    ~debug_data_block(void) {
        RecordDebugEvent(DebugType_CloseDataBlock, DEBUG_NAME("End Data Block"));
    }
};

#define DEBUG_DATA_BLOCK_(Number, BlockName, ...) DEBUG_DATA_BLOCK__(Number, BlockName, __VA_ARGS__)
#define DEBUG_DATA_BLOCK__(Number, BlockName, ...) \
    debug_data_block DataBlock##Number(DEBUG_NAME(BlockName))
#define DEBUG_DATA_BLOCK(...) DEBUG_DATA_BLOCK_(__COUNTER__, __VA_ARGS__)
#define DEBUG_BEGIN_DATA_BLOCK(Name) \
    { RecordDebugEvent(DebugType_OpenDataBlock, DEBUG_NAME(Name)); }

#define DEBUG_END_DATA_BLOCK(Name) \
    { RecordDebugEvent(DebugType_CloseDataBlock, DEBUG_NAME(Name)); }

#define DEBUG_VALUE(Value)                                       \
    {                                                            \
        RecordDebugEvent(DebugType_Unknown, DEBUG_NAME(#Value)); \
        DEBUGValueSetEventData(Event, Value, (void *)&Value);    \
    }

#define DEBUG_NAME_VALUE(Value)                                   \
    {                                                             \
        RecordDebugEvent(DebugType_Unknown, __FUNCTION__ #Value); \
        DEBUGValueSetEventData(Event, Value, (void *)&Value);     \
    }

#define DEBUG_VALUE_TYPE(Value, TYPE)                            \
    {                                                            \
        RecordDebugEvent(DebugType_Unknown, DEBUG_NAME(#Value)); \
        Event->Value_##TYPE = Value;                             \
        Value = Event->Value_##TYPE;                             \
        DEBUGValueSetEventData(Event, (TYPE)0, (void *)&Value);  \
        Event->Type = DebugType_##TYPE;                          \
    }

#define DEBUG_B32(Value) DEBUG_VALUE_TYPE(Value, bool32)

#define DEBUG_THREAD_INTERVAL_GRAPH(FunctionName) \
    { RecordDebugEvent(DebugType_ThreadIntervalGraph, DEBUG_NAME(#FunctionName)); }

#define DEBUG_UI_ELEMENT(Type, Name) \
    { RecordDebugEvent(Type, DEBUG_NAME(#Name)); }

#define DEBUG_BEGIN_ARRAY(...)
#define DEBUG_END_ARRAY(...)
#define DEBUG_END_HOT_ELEMENT(...)
bool32 StringsAreEqual(const char *A, const char *B);

#define DEBUGValueSetEventData_(type)                                                  \
    inline void DEBUGValueSetEventData(debug_event *Event, type Ignore, void *Value) { \
        (void)Ignore;                                                                  \
        Event->Type = DebugType_##type;                                                \
        if (StringsAreEqual(GlobalDebugTable->EditEvent.GUID, Event->GUID)) {          \
            *(type *)Value = GlobalDebugTable->EditEvent.Value_##type;                 \
        }                                                                              \
        Event->Value_##type = *(type *)Value;                                          \
    }

DEBUGValueSetEventData_(uint32);
DEBUGValueSetEventData_(int32);
DEBUGValueSetEventData_(real32);
DEBUGValueSetEventData_(v2);
DEBUGValueSetEventData_(v3);
DEBUGValueSetEventData_(v4);
DEBUGValueSetEventData_(rectangle2);
DEBUGValueSetEventData_(rectangle3);
DEBUGValueSetEventData_(bitmap_id);
DEBUGValueSetEventData_(sound_id);
DEBUGValueSetEventData_(font_id);
DEBUGValueSetEventData_(memory_arena_p);
#endif